import json
import requests
from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

from untils.tencents.cos import delete_file, delete_file_list, credential
from web.forms.file import FileModelForm, CheckFileModelForm
from web import models


def file(request, project_id):
    # 判断当前的url是否携带folder参数，如果有则代表新建文件夹的父目录是当前folder的值
    parent_obj = None
    folder_id = request.GET.get('folder', '')
    if folder_id.isdecimal():
        parent_obj = models.FileRepository.objects.filter(id=folder_id, file_type=1,
                                                          project=request.tracer.project).first()

    if request.method == 'GET':

        parent = parent_obj
        breadcrumb_list = []
        while parent:
            breadcrumb_list.insert(0, {'id': parent.id, 'name': parent.name})
            parent = parent.parent

        if parent_obj:
            file_list = models.FileRepository.objects.filter(project=request.tracer.project,
                                                             parent=parent_obj).order_by('file_type')
        else:
            file_list = models.FileRepository.objects.filter(project=request.tracer.project,
                                                             parent__isnull=True).order_by('file_type')

        form = FileModelForm(request, parent_obj)
        return render(request, 'file.html', {'form': form, 'file_list': file_list, 'breadcrumb_list': breadcrumb_list,
                                             'parent_id': folder_id})

    # 看看前端是否传入fid，如果传入fid则是修改文件夹，没fid则是添加文件夹
    fid = request.POST.get('fid', '')
    # 查询要修改的文件夹
    edit_object = None
    if fid.isdecimal():
        edit_object = models.FileRepository.objects.filter(id=int(fid), file_type=1,
                                                           project=request.tracer.project).first()
    if edit_object:
        # 修改文件夹
        form = FileModelForm(request, parent_obj, data=request.POST, instance=edit_object)
    else:
        # 添加文件夹
        form = FileModelForm(request, parent_obj, data=request.POST)
    if form.is_valid():
        form.instance.project = request.tracer.project
        form.instance.file_type = 1
        form.instance.update_user = request.tracer.user
        form.instance.parent = parent_obj
        form.save()
        return JsonResponse({'status': True})
    return JsonResponse({'status': False, 'errors': form.errors})


def file_delete(request, project_id):
    if request.method == 'GET':
        fid = request.GET.get('fid')

        delete_obj = models.FileRepository.objects.filter(id=fid, project=request.tracer.project).first()

        if delete_obj.file_type == 1:
            # 如果是文件夹则删除文件夹下所有文件的腾讯COS
            total_size = 0
            key_list = []

            folder_list = [delete_obj, ]
            for folder in folder_list:
                child_list = models.FileRepository.objects.filter(project=request.tracer.project,
                                                                  parent=folder).order_by(
                    '-file_type')
                for child in child_list:
                    if child.file_type == 1:
                        folder_list.append(child)
                    else:
                        # 文件大小汇总
                        total_size += child.file_size

                        # 删除文件
                        key_list.append({"Key": child.key})
            # 批量删除

            if key_list:
                delete_file_list(request.tracer.project.bucket, request.tracer.project.region, key_list)
            # 归还总容量
            request.tracer.project.use_space -= total_size
            request.tracer.project.save()
        else:
            # 如果是文件则删除腾讯COS
            request.tracer.project.use_space -= delete_obj.file_size
            request.tracer.project.save()
            delete_file(request.tracer.project.bucket, request.tracer.project.region, delete_obj.key)

        # 删除数据库
        delete_obj.delete()
        return JsonResponse({'status': True})


@csrf_exempt
def cos_credential(request, project_id):
    # 接受前端发送的数据
    upload_file = json.loads(request.body.decode('utf-8'))  # 获取上传的文件名和文件大小
    total_size = 0  # 总的要上传文件的大小
    # 将单文件大小M转换为字节与文件大小进行比较
    for file in upload_file:
        if file['size'] > request.tracer.price_policy.per_file_size * 1024 * 1024:
            msg = f"单个文件{file['name']}大小超出{request.tracer.price_policy.per_file_size}M,请购买套餐"
            return JsonResponse({'status': False, 'error': msg})

        # 计算上传文件的总大小
        total_size += file['size']

    # 项目空间(字节)
    project_space = request.tracer.price_policy.project_space * 1024 * 1024 * 1024
    # 判断当前要上传文件大小和已使用空间大小之和是否大于项目空间，如果大于就报错
    if total_size + request.tracer.project.use_space > project_space:
        return JsonResponse({'status': False, 'error': '项目空间不足,请购买套餐'})

    data_list = credential(request.tracer.project.bucket, request.tracer.project.region)
    return JsonResponse({'status': True, 'data': data_list})


@csrf_exempt
def file_post(request, project_id):
    form = CheckFileModelForm(request, data=request.POST)
    if form.is_valid():
        form.instance.project = request.tracer.project
        form.instance.file_type = 2
        form.instance.update_user = request.tracer.user
        parent_id = request.POST.get('parent_id')
        parent_obj = None
        if parent_id:
            parent_obj = models.FileRepository.objects.filter(id=parent_id, file_type=1,
                                                              project=request.tracer.project).first()
        form.instance.parent = parent_obj
        result = form.save()

        # 将文件计算到项目已使用空间中
        request.tracer.project.use_space += result.file_size
        request.tracer.project.save()
        return JsonResponse({'status': True})
    return JsonResponse({'status': False, 'error': form.errors})


def file_download(request, project_id, file_id):
    '''文件下载'''

    # 通过网络下载需要用到第三方模块requests
    file_obj = models.FileRepository.objects.filter(id=file_id, project_id=project_id).first()
    # 获取该网址的文件内容
    res = requests.get(file_obj.file_path)
    data = res.content
    response = HttpResponse(data)
    from django.utils.encoding import escape_uri_path
    # escape_uri_path用于将中文转换成英文拼音，响应头中不能有中文
    # 设置响应头使浏览器把它当成一个下载的文件
    response['Content-Disposition'] = f"attachment; filename={escape_uri_path(file_obj.name)}"
    return response
